using System;
using System.Drawing;
using System.ComponentModel;

namespace Camalon.Drawing
{
	/// <summary>
	/// Summary description for FPoint.
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(FPointConverter))]
	public struct FPoint
	{
		private PointF _point;

		public FPoint(PointF point)
		{
			_point = point;
		}

		public FPoint(float X, float Y)
		{
			_point = new PointF( X,Y );
		}

		[Browsable(false)]
		public static FPoint Empty
		{
			get{ return new FPoint(0f,0f);}
		}
		[DefaultValue(0.0f)]
		[Category("Points")]
		public float X
		{
			get{ return _point.X;}
			set
			{ 
				_point.X = value;
			}
		}

		[DefaultValue(0.0f)]
		[Category("Points")]
		public float Y
		{
			get{ return _point.Y;}
			set
			{ 
				_point.Y = value;
			}
		}

		[Browsable(false)]
		public PointF PointF
		{
			get{ return _point;}
			set
			{ 
				_point = value;
			}
		}

		[Browsable(false)]
		public Point Point
		{
			get{ return Point.Round( _point );}
			set
			{
				_point = value;
			}
		}

		[Browsable(false)]
		public bool IsEmpty
		{
			get{ return _point.IsEmpty;}
		}

		
		public override bool Equals(object obj)
		{
			if( obj is PointF) return _point.Equals(obj);
			else if ( obj is FPoint ) return this == (FPoint)obj;
			else if ( obj is Point ) return this == (FPoint)obj;

			return false;
		}

		public override int GetHashCode()
		{
			return _point.GetHashCode();
		}

		#region operator FPoint/PointF/Point/PointF
		public static implicit operator PointF(	FPoint point )
		{
			return new PointF(point.X, point.Y );
		}
		public static PointF ToPointF( FPoint point)
		{
			return point;
		}

		public static implicit operator Point(	FPoint point )
		{
			return Point.Round(point);
		}
		public static Point ToPoint(	FPoint point )
		{
			return Point.Round(point);
		}

		public static implicit operator FPoint(	PointF point )
		{
			return new FPoint(point.X, point.Y );
		}
		public static FPoint ToFPoint(PointF point )
		{
			return new FPoint(point.X, point.Y );
		}

		public static implicit operator FPoint(	Point point )
		{
			return new FPoint(point.X, point.Y );
		}
		public static FPoint ToFPoint(	Point point )
		{
			return new FPoint(point.X, point.Y );
		}

		#endregion 

		#region operator ==
		public static bool operator ==(	FPoint point1,FPoint point2	)
		{
			return point1.X == point2.X && point1.Y == point2.Y;
		}

		public static bool operator ==(	FPoint point1,PointF point2	)
		{
			return point1.X == point2.X && point1.Y == point2.Y;
		}

		public static bool operator ==(	PointF point1,FPoint point2	)
		{
			return point1.X == point2.X && point1.Y == point2.Y;
		}

		#endregion 

		#region operator !=
		public static bool operator !=(	FPoint point1,FPoint point2	)
		{
			return point1.X != point2.X || point1.Y != point2.Y;
		}

		public static bool operator !=(	FPoint point1,PointF point2	)
		{
			return point1.X != point2.X || point1.Y != point2.Y;
		}
		public static bool operator !=(	PointF point1,FPoint point2	)
		{
			return point1.X != point2.X || point1.Y != point2.Y;
		}

		#endregion 

		#region operator+
		public static FPoint operator +(	FPoint point,	Size size )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint Add(	FPoint point,	Size size )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint operator +(	Size size, FPoint point )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint Add(	Size size, FPoint point )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}

		public static FPoint operator +(	FPoint point,	SizeF size )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint Add(	FPoint point,	SizeF size )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint operator +(	SizeF size, FPoint point )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		public static FPoint Add(	SizeF size, FPoint point )
		{
			return new FPoint(point.X + size.Width, point.Y+ size.Height);
		}
		
		public static FPoint operator +(	FPoint point1,	FPoint point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}
		public static FPoint Add(	FPoint point1,	FPoint point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}

		public static FPoint operator +(	FPoint point1,	PointF point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}
		public static FPoint Add(	FPoint point1,	PointF point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}

		public static FPoint operator +(	PointF point1,	FPoint point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}
		public static FPoint Add(	PointF point1,	FPoint point2 )
		{
			return new FPoint(point1.X + point2.X, point1.Y+ point1.Y);
		}

		#endregion 

		#region operator-
		public static FPoint operator -(	FPoint point,	Size size )
		{
			return new FPoint(point.X - size.Width, point.Y - size.Height);
		}
		public static FPoint Subtract(	FPoint point,	Size size )
		{
			return new FPoint(point.X - size.Width, point.Y - size.Height);
		}
		public static FPoint operator -(	Size size, FPoint point )
		{
			return new FPoint(point.X - size.Width, point.Y- size.Height);
		}
		public static FPoint Subtract(	Size size, FPoint point )
		{
			return new FPoint(point.X - size.Width, point.Y- size.Height);
		}

		public static FPoint operator -(	FPoint point,	SizeF size )
		{
			return new FPoint(point.X - size.Width, point.Y - size.Height);
		}
		public static FPoint Subtract(	FPoint point,	SizeF size )
		{
			return new FPoint(point.X - size.Width, point.Y - size.Height);
		}
		public static FPoint operator -(	SizeF size, FPoint point )
		{
			return new FPoint(point.X - size.Width, point.Y- size.Height);
		}
		public static FPoint Subtract(	SizeF size, FPoint point )
		{
			return new FPoint(point.X - size.Width, point.Y- size.Height);
		}

		public static FPoint operator -(	FPoint point1,	FPoint point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}
		public static FPoint Subtract(	FPoint point1,	FPoint point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}

		public static FPoint operator -(FPoint point1,	PointF point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}
		public static FPoint Subtract(FPoint point1,	PointF point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}

		public static FPoint operator -(	PointF point1,	FPoint point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}
		public static FPoint Subtract(	PointF point1,	FPoint point2 )
		{
			return new FPoint(point1.X - point2.X, point1.Y - point1.Y);
		}
		#endregion 

	}


}
